package yl.hs.bmipfull.service.system.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import yl.hs.bmipfull.daos.system.IGlobalSearchDao;
import yl.hs.bmipfull.daos.system.IGlobalSearchItemDao;
import yl.hs.bmipfull.daos.system.IPojoSvcDao;
import yl.hs.bmipfull.pojo.system.GlobalSearchEntity;
import yl.hs.bmipfull.pojo.system.GlobalSearchItemEntity;
import yl.hs.bmipfull.service.system.IGlobalSearchService;
import yl.hs.bmipfull.utils.HsApp;
import yl.hs.bmipfull.utils.Tl;
import yl.hs.bmipfull.utils.datastate.ActionType;
import yl.hs.bmipfull.viewmodels.PageQuery;
import yl.hs.bmipfull.viewmodels.PageResult;
import yl.hs.bmipfull.viewmodels.SubmitModel;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * GlobalSearchServiceImpl
 * @category
 * @author 谢景广
 * @date 2021-06-29
 */
@Service
public class GlobalSearchServiceImpl extends SystemBaseService implements IGlobalSearchService {

    @Autowired
    IGlobalSearchItemDao itemDao;

    @Autowired
    IGlobalSearchDao searchDao;

    @Autowired
    IPojoSvcDao pojoSvcDao;

    @Override
    public PageResult<GlobalSearchItemEntity> queryListByPage(PageQuery pageQuery, int page, int pageSize) {
        PageResult<GlobalSearchItemEntity> result = new PageResult(pageSize);
        pageQuery.checkSortSides(GlobalSearchItemEntity.class, "searchCount desc");
        var query = pageQuery.getQuery();
        result.setRecords(itemDao.queryCountByPageSearch(query));
        query.put("querySkip", (page - 1) * pageSize);
        query.put("pageSize", pageSize);
        result.setPage(page);
        result.setData(itemDao.queryListByPageSearch(query));
        return result;
    }

    @Override
    public List<GlobalSearchItemEntity> queryAllItems() {
        return itemDao.queryAllItems();
    }

    @Override
    public Integer deleteDataBySNList(List<String> snList) {
        return itemDao.deleteBySNList(snList);
    }

    @Override
    public Integer saveSearchItem(SubmitModel model) throws Exception {
        int result;
        GlobalSearchItemEntity entity;
        if (Tl.isEmpty(model.getSn())) {
            entity = new GlobalSearchItemEntity();
            Tl.getChangeLog(entity, model.getData());
            entity.setSn(queryNewSN(entity.getClass()));
            result = itemDao.insertNew(entity);
            if (result > 0) {
                writeLog(ActionType.CREATE, entity.getSn(), "创建全局搜索项", entity.toJson(), entity.getClass());
            }
        } else {
            entity = itemDao.findBySN(model.getSn());
            var backJson = entity.toJson();
            var changeLog = Tl.getChangeLog(entity, model.getData());
            result = itemDao.update(entity);
            if (result > 0) {
                writeLog(ActionType.UPDATE, entity.getSn(), changeLog, backJson, entity.getClass());
            }
        }
        return result;
    }

    @Override
    public List<Map<String, Object>> queryItemsByCodes(List<String> userSearchRang) {

        List<Map<String, Object>> result = new ArrayList<>();
        var list = itemDao.queryListByDataCodeList(userSearchRang);
        var user = HsApp.getCurrent();
        if (user != null) {
            var userList = itemDao.queryListByUserSN(user.getUserSN());
            if (list.size() > 0) {
                list.forEach(t -> {
                    int searchCount = 0;
                    var userItem = userList.stream().filter(y -> t.getDataCode().equalsIgnoreCase(y.getDataCode())).findFirst();
                    if (userItem.isPresent()) {
                        searchCount = userItem.get().getSearchCount();
                    } else {
                        try {
                            t.setSn(queryNewSN(t.getClass()));
                            t.setId(null);
                            t.setUserSN(user.getUserSN());
                            itemDao.insertNew(t);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    Map<String, Object> item = new HashMap<>();
                    item.put("dataName", t.getDataType());
                    item.put("dataCode", t.getDataCode());
                    item.put("viewModel", t.getViewModel());
                    item.put("hot", searchCount);
                    result.add(item);

                });
                List<String> deleteSNList = new ArrayList<>();
                userList.forEach(t -> {
                    if (list.stream().noneMatch(p -> t.getDataCode().equalsIgnoreCase(p.getDataCode()))) {
                        deleteSNList.add(t.getSn());
                    }
                });
                if (deleteSNList.size() > 0) {
                    itemDao.deleteBySNList(deleteSNList);
                }
            }
        }
        return result;
    }

    @Override
    public boolean checkDataCode(String dataCode, String oldSN) {
        var entity = itemDao.findItemByCode(dataCode, oldSN);
        return entity != null;
    }

    @Override
    public Map<String, Object> search(String key, String dataCode) {
        List<GlobalSearchEntity> result = searchDao.queryBySearchKey(key, dataCode);
        var codeList = result.stream().map(GlobalSearchEntity::getDataCode).distinct().toList();
        Map<String, Object> map = new HashMap<>();
        for (var code : codeList) {
            Map<String, Object> codeMap = new HashMap<>();
            var dataList = result.stream().filter(t -> t.getDataCode().equals(code)).toList();
            codeMap.put("dataCount", dataList.size());
            var snList = dataList.stream().map(t -> t.getDataSN()).limit(50).toList();
            codeMap.put("dataList", queryDataList(code, snList));
            map.put(code, codeMap);
        }
        return map;
    }

    @Override
    public List<String> tableFieldValueGroupField(String table, String field) {
        return pojoSvcDao.tableFieldValueGroupField(table,field);
    }

    private List<Map<String, Object>> queryDataList(String dataCode, List<String> snList) {
        return pojoSvcDao.queryTableData(dataCode, "sn", snList);
    }
}
